package org.dimock.proxy;

import java.lang.reflect.Method;



public class DefaultMethodResolver implements MethodResolver {
	
	public Method findMatchingMethod(ProxyContext context, Method m) throws NoSuchMethodException, SecurityException{
		String className = trimClassName( m.getDeclaringClass().getName() );
		String methodName  = m.getName();
		String fullyQualified = className + "_" + methodName;
		Integer invocationCount = getInvocationCount(context, fullyQualified) + 1;
		String fullyQualifiedWithCount = className + "_" + methodName +"_" + invocationCount;
		Method found = null;
		try {
			found =  ( context.getRedirect().getClass().getMethod(fullyQualifiedWithCount, m.getParameterTypes()));
			context.recordInvocation(fullyQualified);
			return found;
		} catch (NoSuchMethodException e) {
		}
		if (context.isStrict())
			throw new NoSuchMethodException("Method " + fullyQualifiedWithCount + " not found in " + context.getRedirect().getClass().getName() );
		try {
			found = (context.getRedirect().getClass().getMethod(fullyQualified, m.getParameterTypes()));
			context.recordInvocation(fullyQualified);
			return found;
		} catch (NoSuchMethodException e) {
		}

		try {
			found =   (context.getRedirect().getClass().getMethod(methodName, m.getParameterTypes()));
			context.recordInvocation(methodName);
			return found;
		} catch (NoSuchMethodException e) {
		}

		throw new NoSuchMethodException("Method " + fullyQualifiedWithCount + " or " + fullyQualified + " or " +methodName + " not found in " + context.getRedirect().getClass().getName() );
	}
	
	Integer getInvocationCount(ProxyContext context, String name) {
		return context.getInvocationCount(name);
	}

	String trimClassName(String name){
		if (name == null) return "";
		int pos = name.lastIndexOf(".");
		if ((pos +1) < name.length() )
			return name.substring( name.lastIndexOf(".") + 1);
		return name;
	}

}
